#include "usrlogin.h"
#include "ui_usrlogin.h"
#include "global.h"

UsrLogin::UsrLogin(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::UsrLogin)
{
    ui->setupUi(this);
    rect = parent->geometry();
    windowParent = parent;
}

UsrLogin::~UsrLogin()
{
    delete ui;
}

void UsrLogin::fnInitFormSlots(){
    isInitialization = true;
    int x = rect.width()/2 - this->width() /2;
    int y = rect.height()/2 - this->height()/2;
    this->move(x, y);
    ui->labIcon1->setFont(Global::IconFont);
    ui->labIcon1->setText(QChar(0xed05));
    ui->labIcon2->setFont(Global::IconFont);
    ui->labIcon2->setText(QChar(0xef7a));
    ui->labIcon3->setFont(Global::IconFont);
    ui->labIcon3->setText(QChar(0xed01));
    ui->labIcon4->setFont(Global::IconFont);
    ui->labIcon4->setText(QChar(0xec82));

    connect(ui->BtnUsrCancel, &QPushButton::clicked, this, [=](){ this->close(); });
    connect(ui->BtnUsrLogin, &QPushButton::clicked, this, &UsrLogin::onUsrLogin);
    QList<QLineEdit *> elist = ui->frmWidget->findChildren<QLineEdit *>();
    for(int i = 0; i < elist.size(); i++){
        connect(elist.at(i), &QLineEdit::textChanged, this, &UsrLogin::onTextChanged);
    }
    //滑块验证
    connect(ui->VerifySlider, &QSlider::sliderReleased,this, [=](){
        int valSlider = ui->VerifySlider->value();
        if(valSlider != 100){
            ui->VerifySlider->setValue(0);
            QString tip = ui->labSliderTips->text().replace("OK",">>");
            ui->labSliderTips->setText(tip);
        }else
            ui->labSliderTips->setText(ui->labSliderTips->text().replace(">>","OK"));
    });

    connect(ui->linkUserReg, &QPushButton::clicked, this, &UsrLogin::fnOpenInsidePage);
    connect(ui->linkForgotPasswd, &QPushButton::clicked, this, &UsrLogin::fnOpenInsidePage);
}

void UsrLogin::onTextChanged(){
    if(ui->labPageTips->text() != "请填写完整的登录信息")
        ui->labPageTips->setText("请填写完整的登录信息");
}

/**
 * 上次登录时勾选了保持登录/自动登录
 * @brief UsrLogin::fnChecklogged
 * @param isLogout
 */
void UsrLogin::fnAutomaticLogon(){
    if(Global::usrLoggedInfo.isEmpty())
        return;
    if(!Global::usrLoggedInfo.value("usrKeepLogin").toBool())
        return;
    QDateTime date = QDateTime::fromTime_t(QDateTime::currentDateTimeUtc().toTime_t());
    date.setTimeSpec(Qt::LocalTime);
    uint thisTime = date.toTime_t();
    uint loginTime = Global::usrLoggedInfo.value("timeLogged").toInt();
    if((thisTime - loginTime) > 7*24*60*60)
        return;
    QJsonObject usrInfo;
    usrInfo.insert("usrUid", Global::usrLoggedInfo.value("uid").toString());
    usrInfo.insert("usrAccount", Global::usrLoggedInfo.value("mobile").toString());
    usrInfo.insert("usrPasswd", Global::usrLoggedInfo.value("password").toString());
    usrInfo.insert("usrAuthority", Global::usrLoggedInfo.value("cloudusr").toString());
    ui->BtnUsrLogin->setEnabled(false);
    ui->BtnUsrLogin->setText("自动登录中，请稍候");
    this->fnUserLoginRequest(usrInfo);
}

//用户自行登录
void UsrLogin::onUsrLogin(){
    QJsonObject usrInfo;
    usrInfo.insert("usrAccount", ui->leUsrAccount->text().trimmed());
    usrInfo.insert("usrPasswd", ui->leUsrPasswd->text().trimmed());
    usrInfo.insert("usrKeepLogin", ui->cboxKeepLogin->isChecked());
    if(usrInfo.value("usrAccount").toString() == ""){
        ui->labPageTips->setText("用户名不能为空！");
        return;
    }
    if(usrInfo.value("usrPasswd").toString() == ""){
        ui->labPageTips->setText("密码不能为空！");
        return;
    }
    if(ui->VerifySlider->value() != 100){
        ui->labPageTips->setText("请向右移动滑块完成验证！");
        return;
    }
    ui->BtnUsrLogin->setEnabled(false);
    ui->BtnUsrLogin->setText("登录中，请稍候");
    this->fnUserLoginRequest(usrInfo);
}

//用户登录
void UsrLogin::fnUserLoginRequest(QJsonObject usrInfo){
    QString errMessage = "";
    QString reqResult = "";
    usrInfo.insert("usrAction","UserLogin");
    Global::fnHttpRequest(usrInfo, errMessage, reqResult);

    //登录请求失败
    if(!errMessage.isEmpty()){
        QString err = QString("%1 [Line%2] : %3").arg(__FUNCTION__).arg(__LINE__).arg(errMessage);
        ui->BtnUsrLogin->setText("登录请求失败！");
        QString msg;
        if(usrInfo.value("usrUid").isUndefined()){
            lognum += 1;
            msg = QString("第 %1 次登录请求失败！%2").arg(QString::number(lognum), err);
        }else{
            lognum = 1;
            msg = QString("允许周期内自动登录请求失败！%1").arg(err);
        }
        Global::fnSaveOperation(msg);
        QTimer::singleShot(2000 * lognum, this, [=](){
            ui->BtnUsrLogin->setText("登  录");
            ui->BtnUsrLogin->setEnabled(true);
        });
        return;
    }
    //登录请求成功
    lognum = 0;
    //QString >> QByteArray
    QJsonDocument reqJsonDocument = QJsonDocument::fromJson(reqResult.toUtf8().data());
    if(reqJsonDocument.isNull()){
        Global::fnSaveOperation(QString("%1 [Line%2] : 用户登录请求失败！").arg(__FUNCTION__).arg(__LINE__));
        ui->BtnUsrLogin->setText("登录失败！请联系管理员");
        QTimer::singleShot(3000, this, [=](){
            ui->BtnUsrLogin->setText("登  录");
            ui->BtnUsrLogin->setEnabled(true);
        });
        return;
    }
    //QByteArray >> QJsonObject
    QJsonObject reqJsonObject = reqJsonDocument.object();
    if(reqJsonObject.contains("errMessage")){
        QString errMsg = reqJsonObject.value("errMessage").toString();
        if(errMsg != ""){
            Global::fnSaveOperation(QString("%1 [Line%2] : 用户登录失败！%3").arg(__FUNCTION__).arg(__LINE__).arg(errMsg));
            if(errMsg.contains("非法请求"))
                errMsg = "非法请求";
            if(errMsg.contains("有效数据"))
                errMsg = "无效数据";
            ui->BtnUsrLogin->setText(errMsg);
            QTimer::singleShot(2000, this, [=](){
                ui->BtnUsrLogin->setText("登  录");
                ui->BtnUsrLogin->setEnabled(true);
            });
            return;
        }
    }
    ui->BtnUsrLogin->setText("登录成功，请稍候");
    Global::strAuthority = "0";
    // 超级用户
    QString usrAccount = "";
    if(usrInfo.contains("usrAccount"))
        usrAccount = usrInfo.value("usrAccount").toString();
    if(usrAccount != "" && Global::lstSuperUser.contains(usrAccount))
        Global::strAuthority = "9";
    QString contOperation;
    if(usrInfo.value("usrUid").isUndefined() && !reqJsonObject.contains("keepLogin")){
        // 输入用户名和密码进行的登录
        if(Global::strAuthority == "0")
            Global::strAuthority = reqJsonObject.value("cloudusr").toString();
        Global::usrLoggedInfo = reqJsonObject;
        QString strIdentity = Global::strAuthority == "1" ? "管理员"
                              : Global::strAuthority == "2" ? "普通用户"
                              : Global::strAuthority == "3" ? "游客"
                              : Global::strAuthority == "9" ? "超级用户"
                                                            : "未知";
        if(strIdentity == "未知"){
            QSettings settings(Global::fiConfig, QSettings::IniFormat);
            settings.beginGroup("General");
            settings.remove("usrLoggedInfo");
            settings.endGroup();
            settings.sync();
            Global::strAuthority = "0";
            Global::usrLoggedInfo = QJsonObject();
            QStringList param = {"ShowMessages","4","未知的用户身份！\n请尝试关闭系统，重新进入。"};
            emit MGlobal::fnGetInstance()->CallInsidePageAction(param);
            param.clear();
            return;
        }
        //缓存新的登录信息
        QStringList fiConfigValue;
        fiConfigValue.push_back("/General/usrLoggedInfo");
        fiConfigValue.push_back(QString(QJsonDocument(reqJsonObject).toJson(QJsonDocument::Compact)));
        Global::fnWriteConfigSingle(fiConfigValue);
        fiConfigValue.clear();
        contOperation = QString("用户成功登录系统！登录身份是 %1").arg(strIdentity);
    }else{
        // 自动登录
        if(Global::strAuthority == "0")
            Global::strAuthority = Global::usrLoggedInfo.value("cloudusr").toString();
        contOperation = "因之前勾选保持登录状态，成功自动登录";
    }

    //生成DeviceNumber
    QString UID = Global::usrLoggedInfo.value("uid").toString();
    int random = QRandomGenerator::global()->bounded(1000,9999);
    Global::appDeviceNumber = QString("LrCloudPlatform%1U%2").arg(random).arg(UID);
    Global::fnSaveOperation(contOperation);

    //获取用户设置信息
    QJsonObject postInfo;
    postInfo.insert("usrUid", UID);
    postInfo.insert("usrAction","GetUserSettinsInfo");
    Global::fnHttpRequest(postInfo, errMessage, reqResult);
    if(!errMessage.isEmpty()){
        Global::fnSaveOperation(QString("获取用户信息失败：").arg(errMessage));
    }else{
        //QString >> QByteArray
        QJsonDocument reqJsonDocument = QJsonDocument::fromJson(reqResult.toUtf8().data());
        if(!reqJsonDocument.isNull()){
            //QByteArray >> QJsonObject
            QJsonObject reqJsonObject = reqJsonDocument.object();
            Global::usrSettingsInfo = reqJsonObject;
            Global::fnSaveOperation(QString("用户信息：%1").arg(reqResult));
        }
    }

    // 重置表单
    QTimer::singleShot(2000, this, [=](){
        ui->leUsrAccount->setText("");
        ui->leUsrPasswd->setText("");
        ui->cboxKeepLogin->setChecked(false);
        ui->BtnUsrLogin->setText("登  录");
        ui->BtnUsrLogin->setEnabled(true);
        ui->VerifySlider->setValue(0);
        ui->labSliderTips->setText(ui->labSliderTips->text().replace("OK",">>"));
    });

    QTimer::singleShot(100, this, [=]() {
        QRect popupGeo = this->geometry();
        this->close();
        windowParent->update(popupGeo);
        QApplication::processEvents();
        emit callLoginSucceeded();
        Global::fnSaveOperation("登录界面正常关闭");
    });
}

void UsrLogin::fnOpenInsidePage(){
    QPushButton *button = qobject_cast<QPushButton*>(sender());
    QStringList param = {"OpenInsidePage", button->objectName()};
    emit MGlobal::fnGetInstance()->CallInsidePageAction(param);
    this->close();
}

void UsrLogin::showEvent(QShowEvent*){
    if(!isInitialization)
        fnInitFormSlots();
    this->fnAutomaticLogon();
}
